#include "simplefile_protocol_engine.h"

#include "logger.h"

#undef VERBOSE_DEBUG

const std::string CSimplefileProtocolEngine::sIniSectionName("FPE");
const std::string CSimplefileProtocolEngine::sDefaultReadFilename = "/tmp/read.dat";
const std::string CSimplefileProtocolEngine::sDefaultWriteFilename = "/tmp/write.dat";

CSimplefileProtocolEngine::CSimplefileProtocolEngine(CPropertiesReader* pConfig) :
	mConfig(pConfig),
	mIOFilenameRead(sDefaultReadFilename),
	mIOFilenameWrite(sDefaultWriteFilename),
	mSendEof(true)
{
	std::string lString;
	if (pConfig->containsKey(sIniSectionName, "SEND_EOF"))
	{
		if (pConfig->getValue(sIniSectionName, "SEND_EOF", lString)) {
			mSendEof = lString == "true" ? true : false;
		}
	}
}

CSimplefileProtocolEngine::~CSimplefileProtocolEngine()
{
}

bool CSimplefileProtocolEngine::open()
{
	mIOStreamRead.open(mIOFilenameRead.c_str(), std::ios::in | std::ios::binary);
	mIOStreamWrite.open(mIOFilenameWrite.c_str(),std::ios::out | std::ios::binary | std::ios::trunc);

	return true;
}

void CSimplefileProtocolEngine::close()
{
	if(mIOStreamRead.is_open())
	{
		mIOStreamRead.close();
	}
	if(mIOStreamWrite.is_open())
	{
		mIOStreamWrite.close();
	}
}

int CSimplefileProtocolEngine::available()
{
	// currently not supported -> -1
	// TODO: FIXME: should return the rest of the filesize which can be read
	return -1;
}

NStegIO::EReadState CSimplefileProtocolEngine::read(unsigned char& pReadValue)
{
	if(mIOStreamRead.is_open())
	{
		char lReadValue = 0;
		pReadValue = 0;
		if(mIOStreamRead.good())
		{
			if(mIOStreamRead.read(&lReadValue,1) > 0)
			{
				pReadValue = lReadValue;
#ifdef VERBOSE_DEBUG
				printl(0, "simplefile_protocol_engine.cxx", "Sending byte (data): 0x%02X \n",
						pReadValue);
#endif
				return NStegIO::READ_STATE_DATA;
			}
			else
			{
				if(mIOStreamRead.eof())
				{
#ifdef VERBOSE_DEBUG
					printl(0, "simplefile_protocol_engine.cxx", "Payload successfully sent. \n");
#endif
					mIOStreamRead.close();
					return mSendEof ? NStegIO::READ_STATE_EOF : NStegIO::READ_STATE_NODATA;
				}
			}
		}
		else if (mSendEof) {
			printl(0, "simplefile_protocol_engine.cxx", "Input stream error. \n");
			mIOStreamRead.close();
			return NStegIO::READ_STATE_ERROR;
		}
	}

	return mSendEof ? NStegIO::READ_STATE_ERROR : NStegIO::READ_STATE_NODATA;
}

void CSimplefileProtocolEngine::write(unsigned char pWriteValue)
{
	if(mIOStreamWrite.is_open())
	{
#ifdef VERBOSE_DEBUG
		printl(0, "simplefile_protocol_engine.cxx", "Receiving byte (data): 0x%02X \n",
				pWriteValue);
#endif
		char lWriteValue = pWriteValue;

		mIOStreamWrite.write(&lWriteValue,1);
	}
}
